package com.example.demo.service.impl;

import com.example.demo.entity.User;
import com.example.demo.pojo.PlannerResult;
import com.example.demo.repository.UserRepository;
import com.example.demo.service.UserService;
import com.example.demo.utils.JwtUtil;
import com.example.demo.utils.Md5Util;
import com.example.demo.utils.PlannerCache;
import com.example.demo.vo.UserVo;
import jakarta.annotation.Resource;
import jakarta.mail.internet.InternetAddress;
import jakarta.mail.internet.MimeUtility;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

@Service
public  class UserServiceImpl  implements UserService {

    @Autowired
    UserRepository userRepository;



    @Override
    public PlannerResult<UserVo> login(String account, String password) {

//        Boolean ex = userRepository.existsByEmail(account)||userRepository.existsByPhone(account);
//        // 查不到用户返回登录失败结果
//        if(ex == null){
//            return PlannerResult.error("账号/密码错误，请重新输入！");
//        }
        User user = userRepository.findByPhoneOrEmail(account, account);
        if(user==null){
            return PlannerResult.error("账号/密码错误，请重新输入！");
        }
        // 比对密码
        else {

            Integer is_admin = user.getIs_admin();
            if(!Md5Util.checkPassword(password,user.getPassword()))
                return PlannerResult.error("账号/密码错误，请重新输入！");
            else {
                Map<String,Object> map = new HashMap<>();
                map.put("id",user.getId());
                map.put("account",account);
                map.put("is_admin",is_admin);
                String token = JwtUtil.genToken(map);

                UserVo userVo  = new UserVo();
                userVo.setId(user.getId());
                userVo.setUsername(user.getUsername());
                userVo.setPhone(user.getPhone());
                userVo.setEmail(user.getEmail());
                userVo.setUserToken(token);
                userVo.setAvatar(user.getAvatar());
                userVo.setGender(user.getGender());
                userVo.setCreateTime(user.getCreate_time());
                userVo.setUpdateTime(user.getUpdate_time());
                userVo.setIs_admin(is_admin);

                return PlannerResult.success(userVo);
            }
        }


    }

    /**
     * 注册新用户。
     * 本方法用于处理用户的注册请求。它首先检查是否有相同电话号码或电子邮件地址的用户已存在，
     * 如果存在，则注册失败并返回错误信息。如果不存在，則创建新用户并保存到数据库中。
     *
     * @param user 用户信息，包含用户名、密码、电子邮件和电话号码、验证码
     * @return PlannerResult 字符串类型的规划结果对象，包含注册操作的成功或错误信息。
     */
    @Override
    public PlannerResult<String> register(UserVo user) {
        // 查询是否有相同电话或邮箱的用户已存在
//        boolean xxx1 = userRepository.existsByEmail(user.getEmail()) || userRepository.existsByPhone(user.getPhone());
//        System.out.println(xxx1);

        User u_exist = userRepository.findByPhoneOrEmail(user.getPhone(), user.getEmail());
        if(u_exist!=null){
            return PlannerResult.error("该账号已注册!");
        }
        // 如果存在相同电话或邮箱的用户，则注册失败
//        if(!xxx1) {
//            return PlannerResult.error("该账号已注册!");
//        }

        String regex = "\\d{11}";
        if (user.getUsername().matches(regex)) {
            return PlannerResult.error("用户名不能为11位数字！");
        }

        if (StringUtils.hasText(user.getPhone()) && StringUtils.hasText(user.getEmail())) {
            return PlannerResult.error("手机号与邮箱只能选择其中一个！");
        }

        if (StringUtils.hasText(user.getPhone())) {
            Integer codeCache = (Integer) PlannerCache.get(user.getPhone());
            if (codeCache == null || codeCache != Integer.parseInt(user.getCode())) {
                return PlannerResult.error("验证码错误！");
            }
            PlannerCache.remove(user.getPhone());
        } else if (StringUtils.hasText(user.getEmail())) {
            Integer codeCache = (Integer) PlannerCache.get(user.getEmail());
            if (codeCache == null || codeCache != Integer.parseInt(user.getCode())) {
                return PlannerResult.error("验证码错误！");
            }
            PlannerCache.remove(user.getEmail());
        } else {
            return PlannerResult.error("请输入邮箱或手机号！");
        }

        // 创建新用户对象，并设置用户名、密码、邮箱和电话
        User u = new User();
        u.setUsername(user.getUsername());
        u.setPassword(Md5Util.getMD5String(user.getPassword()));
        u.setEmail(user.getEmail());
        u.setPhone(user.getPhone());
        u.setGender(0);
        u.setUpdate_time(LocalDateTime.now());
        u.setAvatar("https://www.bilibili.com/favicon.ico?v=1");
        u.setCreate_time(LocalDateTime.now());
        u.setIs_admin(0);
        // 将新用户插入数据库
        userRepository.save(u);
        // 注册成功，返回成功信息
        return PlannerResult.success("注册成功!");
    }

    @Resource
    JavaMailSender javaMailSender;

    private final static Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);
    /**
     * 发送验证码。
     * 本方法用于发送验证码，根据传入的标识符（可以是电话号码或电子邮件地址）来确定发送验证码的方式。
     * 如果标识符是电话号码，则发送短信验证码；如果标识符是电子邮件地址，则发送电子邮件验证码。
     *
     * @param identifier 标识符，可以是电话号码或电子邮件地址。
     *
     */
    @Override
    public PlannerResult<String> sendEmailVerificationCode(String identifier) {

        if(identifier.matches("^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$")) {
            // 发送电子邮件验证码
            SimpleMailMessage message = new SimpleMailMessage();
            Random random = new Random();
            int i=random.nextInt(899999)+100000;
            PlannerCache.put(identifier,i,300);
            try {
                message.setFrom(new InternetAddress(MimeUtility.encodeText("活动管理系统官方: ")+"<1973834626@qq.com>").toString());
                message.setTo(identifier);
                message.setSubject("活动管理系统验证码");
                message.setText("好兄弟,验证码是："+i+" ,别乱传啊!");
                javaMailSender.send(message);
                logger.info("邮件发送成功");
                logger.info("验证码：{}", i);
                return PlannerResult.success("邮件发送成功,验证码5分钟后过期,验证码："+i);
            } catch (Exception e) {
                logger.error("邮件发送失败",e);
            }
        }
        return PlannerResult.error("邮件发送失败");
    }

    @Override
    public PlannerResult<String>  sendPhoneVerificationCode(String identifier) {
        if(identifier.matches("^1[3456789]\\d{9}$")) {
            // 发送电子邮件验证码
            SimpleMailMessage message = new SimpleMailMessage();
            Random random = new Random();
            int i=random.nextInt(899999)+100000;
            try {
                PlannerCache.put(identifier,i,300);
                logger.info("短信发送成功");
                logger.info("验证码：{}", i);
                return PlannerResult.success("短信发送成功,验证码5分钟后过期,验证码："+i);
            } catch (Exception e) {
                logger.error("短信发送失败",e);
            }
        }
        return PlannerResult.error("短信发送失败");
    }

    @Override
    public PlannerResult<String> find_password(String account, String password, String code) {

        User user = userRepository.findByPhoneOrEmail(account, account);
        if(user==null){
            return PlannerResult.error("该账号不存在");
        }

        if (account.matches("^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$")){
            Integer codeCache = (Integer) PlannerCache.get(account);
            if (codeCache == null || codeCache != Integer.parseInt(code)) {
                return PlannerResult.error("验证码错误！");
            }
            PlannerCache.remove(account);

            // 发送电子邮件密码
            SimpleMailMessage message = new SimpleMailMessage();
            try {
                message.setFrom(new InternetAddress(MimeUtility.encodeText("活动管理系统官方: ")+"<1973834626@qq.com>").toString());
                message.setTo(account);
                message.setSubject("活动管理系统密码找回");
                message.setText("好兄弟,新密码是："+password+" ,别乱传啊!");
                javaMailSender.send(message);
                logger.info("邮件发送成功");

                user.setPassword(Md5Util.getMD5String(password));
                userRepository.save(user);

                return PlannerResult.success();
            } catch (Exception e) {
                logger.error("邮件发送失败",e);
            }

            return PlannerResult.error("密码重置失败");
        }else{
            Integer codeCache = (Integer) PlannerCache.get(account);
            if (codeCache == null || codeCache != Integer.parseInt(code)) {
                return PlannerResult.error("验证码错误！");
            }
            PlannerCache.remove(account);
            return PlannerResult.error("密码重置失败,只支持邮箱找回");
        }
    }
}
